﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Net;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Windows.Forms;

namespace UriInspect
{
    public partial class Form1 : Form
    {
        #region Attributes

        private string DefaultDate = "未收录";

        private string BaiDuSearch = @"http://www.baidu.com/s?wd={keywords}";
        private string BaiDuRegex = "adata-click.*href=\"(?<url>((http://)*{url}(/)*))\"target=\"_blank\">(?<title>(.*))</a></h3>.*(?<date>((\\d{4}-\\d{1,2}-\\d{1,2})|(\\d{1,2}小时前)))</span>";

        private Thread myThread = null;
        private delegate void myDelegate(SearchResult Result);
        private static ManualResetEvent Threadmre = new ManualResetEvent(true);

        private bool IsPause = false;

        #endregion

        #region Form

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_SizeChanged(object sender, EventArgs e)
        {
            this.tabControl1.Refresh();

            if (this.WindowState == FormWindowState.Minimized)
            {
                this.Visible = false;
            }
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            e.Cancel = true;
            if (myThread != null && myThread.IsAlive)
            {
                if (MessageBox.Show("正在进行检查操作，确认要退出吗？", "系统提示", MessageBoxButtons.OKCancel, MessageBoxIcon.Question) == DialogResult.Cancel)
                {
                    return;
                }
                myThread.Abort();
            }
            e.Cancel = false;
        }

        #endregion

        #region Event

        #region Button

        #region Input

        private void btnStartCheck_Click(object sender, EventArgs e)
        {
            InitListView();
            SetCheck(false);
            myThread = new Thread(new ThreadStart(ThreadCheck));
            myThread.Start();
            IsPause = false;
        }

        private void btnPauseCheck_Click(object sender, EventArgs e)
        {
            if (IsPause)
            {
                Threadmre.Set();
                IsPause = false;
                this.btnPauseCheck.Text = "暂停";
            }
            else
            {
                Threadmre.Reset();
                IsPause = true;
                this.btnPauseCheck.Text = "继续";
            }
        }

        private void btnCancelCheck_Click(object sender, EventArgs e)
        {
            if (myThread != null && myThread.IsAlive)
            {
                if (MessageBox.Show("正在进行检查操作，确认要退出吗？", "系统提示", MessageBoxButtons.OKCancel, MessageBoxIcon.Question) == DialogResult.Cancel)
                {
                    return;
                }
                myThread.Abort();
            }
            SetCheck(true);
        }

        #endregion

        #region Gather

        private void btnStartGather_Click(object sender, EventArgs e)
        {
            InitListView();
            SetGather(false);
            myThread = new Thread(new ThreadStart(ThreadGather));
            myThread.Start();
            IsPause = false;
        }

        private void btnPauseGather_Click(object sender, EventArgs e)
        {
            if (IsPause)
            {
                Threadmre.Set();
                IsPause = false;
                this.btnPauseGather.Text = "暂停";
            }
            else
            {
                Threadmre.Reset();
                IsPause = true;
                this.btnPauseGather.Text = "继续";
            }
        }

        private void btnCancelGather_Click(object sender, EventArgs e)
        {
            if (myThread != null && myThread.IsAlive)
            {
                if (MessageBox.Show("正在进行检查操作，确认要退出吗？", "系统提示", MessageBoxButtons.OKCancel, MessageBoxIcon.Question) == DialogResult.Cancel)
                {
                    return;
                }
                myThread.Abort();
            }
            SetGather(true);
        }

        #endregion

        #endregion

        #endregion

        #region Thread&DeleGate

        private void ThreadGather()
        {
            try
            {
                Threadmre.Set();
                for (int i = (int)this.nudStart.Value; i <= (int)this.nudEnd.Value; i++)
                {
                    string HtmlData = GetHtml(this.tbUrl.Text.Trim().Replace("{id}", i.ToString()), "", Encoding.UTF8);
                    Regex regex = new Regex(this.tbUrlRegex.Text.Trim(), RegexOptions.IgnoreCase);
                    MatchCollection mc = regex.Matches(HtmlData);
                    foreach (Match mt in mc)
                    {
                        string BaiDuHtml = GetHtml(BaiDuSearch.Replace("{keywords}", mt.Value), "", Encoding.UTF8).Replace(" ", "").Replace("\n", "").Replace("\r", "");
                        SearchResult Result = new SearchResult();
                        Result = GetData(BaiDuHtml, mt.Value);
                        Threadmre.WaitOne();
                        this.lvResult.Invoke(new myDelegate(ListViewAdd), new object[] { Result });

                        Thread.Sleep((int)this.nudInterval.Value * 1000);
                    }
                }

                SetGather(true);
            }
            catch (ThreadAbortException)
            {
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        private void ThreadCheck()
        {
            try
            {
                foreach (string url in this.rtbList.Lines)
                {
                    if (string.IsNullOrEmpty(url)) continue;

                    string HtmlData = GetHtml(BaiDuSearch.Replace("{keywords}", url), "", Encoding.UTF8).Replace(" ", "").Replace("\n", "").Replace("\r", "");
                    SearchResult Result = new SearchResult();
                    Result = GetData(HtmlData, url.Trim());
                    this.lvResult.Invoke(new myDelegate(ListViewAdd), new object[] { Result });

                    Thread.Sleep((int)this.nudInterval.Value * 1000);
                }

                SetCheck(true);
            }
            catch (ThreadAbortException)
            {
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        #endregion

        #region ListView

        private void InitListView()
        {
            this.lvResult.Items.Clear();
        }

        private void ListViewAdd(SearchResult Result)
        {
            ListViewItem item = new ListViewItem();
            item.SubItems[0].Text = (this.lvResult.Items.Count + 1).ToString();
            item.SubItems.Add(Result.title);
            item.SubItems.Add(Result.url);
            item.SubItems.Add(Result.date);
            if (Result.date == DefaultDate)
            {
                item.UseItemStyleForSubItems = true;
                item.ForeColor = Color.Red;
            }
            this.lvResult.Items.Add(item);

        }

        #endregion

        #region Method

        private void SetCheck(bool b)
        {
            this.rtbList.Enabled = b;
            this.btnStartCheck.Enabled = b;
            this.btnPauseCheck.Enabled = !b;
            this.btnCancelCheck.Enabled = !b;
            this.pGather.Enabled = b;
            this.pSetting.Enabled = b;
        }

        private void SetGather(bool b)
        {
            this.btnStartGather.Enabled = b;
            this.btnPauseGather.Enabled = !b;
            this.btnCancelGather.Enabled = !b;
            this.pCheck.Enabled = b;
            this.pSetting.Enabled = b;
        }

        #region Gather

        //通过url对应获取快照时间
        private SearchResult GetData(string HtmlData, string url)
        {
            SearchResult sr = new SearchResult();
            sr.url = url;
            Regex reg = new Regex("<table(.*?)</table>", RegexOptions.IgnoreCase);

            MatchCollection mc = reg.Matches(HtmlData);
            foreach (Match mt in mc)
            {
                Regex myRegex = new Regex(BaiDuRegex.Replace("{url}", url), RegexOptions.IgnoreCase);
                MatchCollection myMatchCollection = myRegex.Matches(mt.Value);
                if (myMatchCollection.Count > 0)
                {
                    foreach (Match myMatch in myMatchCollection)
                    {
                        Regex cpRegex = new Regex("^(http://)*{url}(/)*$".Replace("{url}", url), RegexOptions.IgnoreCase);

                        if (cpRegex.IsMatch(myMatch.Groups["url"].Value))
                        {
                            sr.title = myMatch.Groups["title"].Value.Replace(@"<em>","").Replace(@"</em>","");
                            sr.date = myMatch.Groups["date"].Value;
                            break;
                        }
                    }
                }
            }
            if (string.IsNullOrEmpty(sr.date))
            {
                string myData = GetHtml(sr.url, "", Encoding.Default);
                Regex myRegex = new Regex("<title>(.*)</title>", RegexOptions.IgnoreCase);
                sr.title = myRegex.Match(myData).Groups[1].Value;
                sr.date = DefaultDate;
            }
            return sr;
        }

        //获取网页源代码
        private string GetHtml(string url, string ref_url,Encoding encode)
        {
            string outHtmlData = "";
            try
            {
                HttpWebRequest httpWebRequest = (HttpWebRequest)HttpWebRequest.Create(url);
                httpWebRequest.Referer = ref_url;
                httpWebRequest.ContentType = "application/x-www-form-urlencoded";
                httpWebRequest.Accept = "image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/x-shockwave-flash, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, */*";
                httpWebRequest.UserAgent = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0; .NET CLR 1.1.4322; .NET CLR 2.0.50727,; .NET CLR 3.0.04506,; .NET CLR 3.5.21022)";
                httpWebRequest.Method = "GET";
                HttpWebResponse webResponse = (HttpWebResponse)httpWebRequest.GetResponse();
                if (webResponse.StatusCode == HttpStatusCode.OK)
                {
                    StreamReader sr = new StreamReader(webResponse.GetResponseStream(), encode);
                    outHtmlData = sr.ReadToEnd();
                    sr.Close();
                }
                else
                {
                    outHtmlData = "";
                }
                webResponse.Close();
            }
            catch (ThreadAbortException)
            {
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
            return outHtmlData;
        }

        #endregion

        #endregion

        #region contextStripMenu

        private void ToolStripMenuItem_ExportSelect_Click(object sender, EventArgs e)
        {
            this.saveFileDialog1.ValidateNames = true;
            this.saveFileDialog1.Filter = "日志文件(*.log)|*.log|CSV文件(*.csv)|*.csv|Excel文件(*.xls)|*.xls";
            this.saveFileDialog1.FilterIndex = 1;
            this.saveFileDialog1.DefaultExt = "log";
            this.saveFileDialog1.FileName = "";
            this.saveFileDialog1.AddExtension = true;
            if (this.saveFileDialog1.ShowDialog() == DialogResult.Cancel)
            {
                return;
            }

            if (this.saveFileDialog1.FileName.EndsWith(".xls"))
            {
                if (Export.Export2Excel(lvResult, lvResult.SelectedItems, this.saveFileDialog1.FileName))
                {
                    MessageBox.Show("导出成功");
                }
                else
                {
                    MessageBox.Show("操作失败");
                    return;
                }
            }
            else
            {
                if (Export.Export2Txt(lvResult, lvResult.SelectedItems, this.saveFileDialog1.FileName))
                {
                    MessageBox.Show("导出成功");
                }
                else
                {
                    MessageBox.Show("操作失败");
                    return;
                }
            }
        }

        private void ToolStripMenuItem_ExportAll_Click(object sender, EventArgs e)
        {
            this.saveFileDialog1.ValidateNames = true;
            this.saveFileDialog1.Filter = "日志文件(*.log)|*.log|CSV文件(*.csv)|*.csv|Excel文件(*.xls)|*.xls";
            this.saveFileDialog1.FilterIndex = 1;
            this.saveFileDialog1.DefaultExt = "log";
            this.saveFileDialog1.FileName = "";
            this.saveFileDialog1.AddExtension = true;
            if (this.saveFileDialog1.ShowDialog() == DialogResult.Cancel)
            {
                return;
            }

            if (this.saveFileDialog1.FileName.ToLower().EndsWith(".xls"))
            {
                if (Export.Export2Excel(lvResult, this.saveFileDialog1.FileName))
                {
                    MessageBox.Show("导出成功");
                }
                else
                {
                    MessageBox.Show("操作失败");
                    return;
                }
            }
            else if (this.saveFileDialog1.FileName.ToLower().EndsWith(".csv"))
            {
                if (Export.Export2CSV(lvResult, this.saveFileDialog1.FileName))
                {
                    MessageBox.Show("导出成功");
                }
                else
                {
                    MessageBox.Show("操作失败");
                    return;
                }
            }
            else
            {
                if (Export.Export2Txt(lvResult, this.saveFileDialog1.FileName))
                {
                    MessageBox.Show("导出成功");
                }
                else
                {
                    MessageBox.Show("操作失败");
                    return;
                }
            }
        }

        private void ToolStripMenuItem_Main_Click(object sender, EventArgs e)
        {
            this.Visible = true;
            this.WindowState = FormWindowState.Normal;
        }

        #endregion

        private void notifyIcon1_DoubleClick(object sender, EventArgs e)
        {
            ToolStripMenuItem_Main_Click(sender, e);
        }

        private void lvResult_MouseClick(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                ListViewItem item = ((CustomListView)sender).GetItemAt(e.X, e.Y);
                ListViewItem.ListViewSubItem portSubItem = item.GetSubItemAt(e.X, e.Y);
                int intColIndex = item.SubItems.IndexOf(portSubItem);//这个就是列索引了
                switch (intColIndex)
                {
                    case 2:
                        System.Diagnostics.Process.Start(portSubItem.Text);
                        break;
                    case 3:
                        System.Diagnostics.Process.Start(BaiDuSearch.Replace("{keywords}", item.SubItems[2].Text));
                        break;
                    default:
                        break;
                }
            }
        }
    }

    public struct SearchResult
    {
        public string url;
        public string title;
        public string date;
    }

    public class CustomListView : ListView
    {
        public CustomListView()
        {
            SetStyle(ControlStyles.DoubleBuffer | ControlStyles.OptimizedDoubleBuffer | ControlStyles.AllPaintingInWmPaint, true);
            UpdateStyles();
        }
    }
}
